import datetime
import math

import common
import utils
import warningExtractor
import stormReportExtractor
import radarExtractor

def numWarnings(years, minDist = -1, maxDist = -1):
	if minDist == -1 and maxDist == -1:
		return len(warningExtractor.loadTorWarnings(years))
	else:
		warnings = warningExtractor.loadTorWarnings(years)
		distValidWarnings = []
		for warn in warnings:
			dist = utils.latLonDist(warn["countyLatLon"], common.KTLXLocation)
			if dist <= maxDist and dist >= minDist:
				distValidWarnings.append(warn)
		return len(distValidWarnings)

def numTorReports(years, minDist = -1, maxDist = -1):
	if minDist == -1 and maxDist == -1:
		return len(stormReportExtractor.loadStormReports(years))
	else:
		reps = stormReportExtractor.loadStormReports(years)
		distValidReps = []
		for rep in reps:
			dist = utils.latLonDist((rep['slat'], rep['slon']), common.KTLXLocation)
			if dist <= maxDist and dist >= minDist:
				distValidReps.append(rep)
		return len(distValidReps)

def printWarnings(years):
	print 'loading warnings...'
	warnings = warningExtractor.loadTorWarnings(years)
	print '%d warnings'%len(warnings)
	fout = open('warning-list.txt', 'w')
	
	warnings.sort(key = lambda x:x['iTime'])
	
	for warn in warnings:
		baseRef = radarExtractor.getClosestRadarData(warn["iTime"], num = 0, products=['baseRef0'])
		if len(baseRef) == 0: continue
		
		radarFile = baseRef[0].split('\\')[-1].split('.')[0][-12:]
		fout.write("%s, %s, %s,\n\n"%(warn['countyName'], warn['iTime'], radarFile))
		
	fout.flush()
	fout.close()
	
def findActiveDays(warnings = [], reports = [], years = [], touchdown = False, toFile = False, fileName = 'active-warnings.txt', verbose = False):
	if len(warnings) == 0 and len(reports) == 0 and len(years) == 0:
		print 'must pass in warnings and reports or years'
		return []
	
	if verbose:
		print 'loading warnings...'
	if len(warnings) == 0:
		warnings = warningExtractor.loadTorWarnings(years)
	
	if touchdown and len(reports) == 0:
		reports = stormReportExtractor.loadStormReports(years)
	
	if verbose:
		print '%d warnings, %d tor reports'%(len(warnings), len(reports))
	
	fout = None
	
	if toFile:
		fout = open(fileName, 'w')

	activeDays = {}
	if verbose:
		print 'searching warnings...'
		
	for warn in warnings:
		matchingTors = []
		if touchdown:
			matchingTors = matchStormWithWarning(warn, reports)
			if len(reports) == 0:
				continue
		
		warnTime = warn['iTime']
		curDate = datetime.datetime(warnTime.year, warnTime.month, warnTime.day)
		if str(curDate) in activeDays.keys():
			activeDays[str(curDate)] += len(matchingTors)
		else:
			activeDays[str(curDate)] = len(matchingTors)

	for day in sorted(activeDays.keys()):
		if toFile: fout.write('%s,%d\n'%(day, activeDays[day]))
		if verbose:
			print '%s,%d\n'%(day, activeDays[day])
	
	if toFile:
		fout.flush()
		fout.close()
	return activeDays

def findRequiredRadarDays(years):
	days = findActiveDays(years = years)
	for day in days.keys()[:]:
		dayDateTime = datetime.datetime.strptime(day, "%Y-%m-%d %H:%M:%S")
		dayMinusOne = dayDateTime+datetime.timedelta(days = -1)
		if str(dayMinusOne) not in days.keys():
			days[str(dayMinusOne)] = 0
	
	
	keys = days.keys()
	return sorted(keys)
	

def matchStormWithWarning(warning, reports = None):
	"""Finds storm reports for a particular tornado warning"""
	warningITime = warning["iTime"]
	warningETime = warning["eTime"]
	warningCounty = warning['countyCode']

	if reports == None:
		reports = stormReportExtractor.loadStormReports([warningITime.year])

	matchingReports = []
	nCounty = 0
	nTime = 0
	for rep in reports:
		# report in warned county?
		if rep['fips1'] == warningCounty:
			if rep['time'] >= warningITime and rep['time'] <= warningETime:
				matchingReports.append(rep)
	return matchingReports

def findUnwarnedTornadoes(years = [], warnings = [], reports = []):
	if len(warnings) == 0:
		print 'loading warnings...'
		warnings = warningExtractor.loadTorWarnings(years)
	if len(reports) == 0:
		print 'loading reports...'
		reports = stormReportExtractor.loadStormReports(years)
	
	unWarnedStorms = []
	for rep in reports:
		warned = False
		for warn in warnings:
			match = matchStormWithWarning(warn, reports)
			if rep in match:
				warned = True
				break
		if not warned:
			unWarnedStorms.append(rep)

	return unWarnedStorms

def calcUnwarnedRate(years = [], warnings = [], reports = []):
	if len(warnings) == 0:
		print 'loading warnings...'
		warnings = warningExtractor.loadTorWarnings(years)
	if len(reports) == 0:
		print 'loading reports...'
		reports = stormReportExtractor.loadStormReports(years)
	
	unwarned = findUnwarnedTornadoes(warnings = warnings, reports = reports)
	
	return float(len(unwarned))/len(reports)
	
def far(warnings = None, reports = None, years = [2010]):
	"""Calculates the tornado warning false alarm rate."""
	if warnings == None:
		print 'loading warnings...'
		warnings = warningExtractor.loadTorWarnings(years)
	if reports == None:
		print 'loading reports...'
		reports = stormReportExtractor.loadStormReports(years)

	noFar = 0
	for warn in warnings:
		repMatches = matchStormWithWarning(warn, reports)
		if len(repMatches) > 0:
			noFar += 1
		
	return 1-(float(noFar)/len(warnings))

def totalStats():
	yStart = 2000
	yEnd = 2010
	print 'loading warnings...'
	warnings = warningExtractor.loadTorWarnings(years = range(yStart,yEnd+1))
	print 'loading reports...'
	reports = stormReportExtractor.loadStormReports(years = range(2000,2010+1))
	f = far(warnings = warnings, reports = reports)
	u = calcUnwarnedRate(warnings = warnings, reports = reports)
	print
	print 'years: %d-%d:'%(yStart, yEnd)
	print 'far = %.2f, unwarned rate = %.2f'%(f, u)
	

def yearlyStats():
	fout = open('yearly-stats.csv', 'w')
	for year in range(2000,2010+1):
		warnings = warningExtractor.loadTorWarnings(years = [year])
		reports = stormReportExtractor.loadStormReports(years = [year])
		f = far(warnings = warnings, reports = reports)
		u = calcUnwarnedRate(warnings = warnings, reports = reports)
		fout.write('%d\t%f\t%f\n'%(year, f, u))
	fout.flush()
	fout.close()
		
